#!/usr/bin/env python
# -*- coding: UTF-8 -*-

__version__ = "0.1.8"
__date__ = "2011-03-20"

HEADER24="Date,Time,Station,Sensor,Latitude,Longitude,Temperature,Counts"

import csv
from lightmeter import lightmeter,lighttime,toint,tofloat,tostr,booltostr,strtobool
from datetime import datetime, timedelta
from optparse import OptionParser

def detectversion(filename_in):
    fh_in = open(filename_in,'rb')
    line = fh_in.readline()
    if len(line)>=len(HEADER24) and line[:len(HEADER24)]==HEADER24:
        return 2.4
    else:
        return 2.3

def reader23(filename_in,step=1,latitude=None,longitude=None,station=None,sensor=None,version=None,verbose=None,debug=None):
    fh_in = open(filename_in,'rb')
    
    data = []
    s =1
    
    for line in fh_in.readlines():
        
        if s>=step:
            line= line.split()
            if debug:
                print line
            
            if len(line)>=1 and line[0][0] == '#':
                
                if len(line)==3:
                    commment,tag,value = line
                    if tag=='STATION:' and not station:
                        station=tostr(value)
                    if tag=='SENSOR:' and not sensor:
                        sensor=toint(value)
                    if tag=='VERSION:' and not version:
                        version=tostr(value)
                    if tag=='LATITUDE:' and not latitude:
                        latitude=tofloat(value.replace(',','.'))
                    if tag=='LONGITUDE:' and not longitude:
                        longitude=tofloat(value.replace(',','.'))
            else:
                if len (line)==1:
                    line=line[0].replace(',','.').split(';')
                    if len(line)==9:
                        date,time,temperature,celsius,counts,visual,infrared,status=line[:8]
                        date=date.split('.')
                        time=time.split(':')
                        lt = lighttime(
                            int(date[2]),int(date[1]),int(date[0]),
                            int(time[0]),int(time[1]),int(time[2])
                        )
                        lm = lightmeter(
                            station=tostr(station),
                            sensor=tostr(sensor),
                            version=tostr(version),
                            latitude=tofloat(latitude),
                            longitude=tofloat(longitude),
                            temperature=tofloat(temperature),
                            counts=toint(counts),
                            visual=toint(visual),
                            infrared=toint(infrared),
                            status=strtobool(status)
                        )
                        data.append((lt,lm))
            s=1
        else:
            s+=1
                    
            
    fh_in.close()
            
    return data
    
 

def reader24(filename_in,step=1,latitude=None,longitude=None,station=None,sensor=None,verbose=None,debug=None):
    fh_in = open(filename_in,'rb')
    cdict = csv.DictReader(fh_in)
    data = []
    s =1
    for line in cdict:
        if s>=step:
            lm = lightmeter()
            date = line['Date']
            time = line['Time']
            lt = lighttime(
                int(date[0:4]),int(date[5:7]),int(date[8:10]),\
                int(time[0:2]),int(time[3:5]),int(time[6:8]),int(time[9:13])*1000
            )
            status = line['Status']
            temperature= line['Temperature']
            light=line['Light']
            try:
                visual=line['Visual']
                infrared=line['Infrared']
            except KeyError:
                visual = None
                infrared= None
            counts=line['Counts']
            if not longitude:
                longitude=line['Longitude']
            if not latitude:
                latitude=line['Latitude']
            if not station:
                station=line['Station']
            if not sensor:
                sensor=line['Sensor']            
            lm = lightmeter(
                        station=tostr(station),
                        sensor=tostr(sensor),
                        latitude=tofloat(latitude),
                        longitude=tofloat(longitude),
                        temperature=tofloat(temperature),
                        counts=toint(counts),
                        visual=toint(visual),
                        infrared=toint(infrared),
                        status=strtobool(status)
            )
            data.append((lt,lm))
            s=1
        else:
            s+=1
    
    fh_in.close()
            
    return data
    
    
def reader(filename_in,step=1,sensor=None,latitude=None,longitude=None,station=None,verbose=None,debug=None):
        
    version = detectversion(filename_in)
    
    data = []
    
    if version == 2.4:
        if verbose:
            print "Detected version 2.4."
        return reader24(filename_in=filename_in,\
            step=toint(step),\
            station = station,\
            sensor=sensor,\
            latitude=latitude,\
            longitude=longitude,\
            verbose=verbose,\
            debug=debug
        )
    else:
        if verbose:
            print "Detected version 2.3."
        return reader23(filename_in=filename_in,\
            step=toint(step),\
            station = station,\
            sensor=sensor,\
            latitude=latitude,\
            longitude=longitude,\
            verbose=verbose,\
            debug=debug
        )
    
    
def writer23(cvsout,data):
    if not data:
        exit(-1)
    fhout = open(cvsout,'wb')
    lt,lm=data[0]
    lm.setversion()
    fhout.write(lm.header23()+'\n')
    for line in data:
        lt,lm=line
        fhout.write(lt.line23()+';'+lm.line23()+'\n')
    fhout.close()
    
def writer24(cvsout,data):
    if not data:
        exit(-1)
    fhout = open(cvsout,'wb')
    lt,lm=data[0]
    lm.setversion()
    fhout.write(lt.header24()+','+lm.header24()+'\n')
    
    for line in data:
        lt,lm=line
        fhout.write(lt.line24()+','+lm.line24()+'\n')
    
    fhout.close()

def get_utc(data):
    time=[]
    for line in data:
        time.append(line[0])
        
    return time

def get_counts(data):
    counts=[]
    for line in data:
        counts.append( line[1].counts)
        
    return counts
    
def get_temperature(data):
    temperature=[]
    for line in data:
        temperature.append( line[1].temperature)
        
    return temperature
    

def main():
    parser = OptionParser()
    parser.add_option("-i","--filename-in", dest="filename_in", default='', metavar="file",
                                      help="csv filename in")
    parser.add_option("-o","--filename-out", dest="filename_out", default='', metavar="file",
                                      help="csv filename out")
    parser.add_option("-t","--type-out", dest="type", default='2.4', metavar="file",
                                      help="version 2.3 or 2.4"),
    parser.add_option("-n","--station", dest="station", default="", metavar="id",
                                      help="station id")
    parser.add_option("-s","--sensor", dest="sensor", default="", metavar="snr",
                                      help="sensor serial number")
    parser.add_option("--lat", dest="latitude", default="", metavar="latitude",
                                      help="set latitude")
    parser.add_option( "--lon",dest="longitude", default="", metavar="longitude",
                                      help="set longitude")
    parser.add_option("--step", dest="step", default="1", metavar="step",
                                      help="step value for reading data [%default]")
                                      
    parser.add_option("-v", "--verbose",action="store_true", dest="verbose", default=False,
                                      help="be verbose")
    parser.add_option("-d","--debug", dest="debug", default=False, action="store_true",
                                      help="enable debug")
    (options, args) = parser.parse_args()
    
    if not options.filename_in or not options.filename_out:
        parser.print_help()
        exit(-1) 
        
    data = reader(filename_in=options.filename_in,\
                  station = options.station,\
                  sensor = options.sensor,\
                  latitude = options.latitude,\
                  longitude = options.longitude,\
                  step = options.step,\
                  verbose=options.verbose,\
                  debug=options.debug)
                  
    if options.debug:
        print data 
        
    if options.type=='2.3':
        print "Writing version 2.3 to",options.filename_out
        writer23(options.filename_out,data)
    elif options.type=='2.4':
        print "Writing version 2.4 to",options.filename_out
        writer24(options.filename_out,data)
    else:
        parser.print_help()
        exit(-1)
    
if __name__ == "__main__":
    main()
